/*
 * Copyright @ 2024 weili23
 * com.itheima.mp.service.impl 10:24
 * All right reserved.
 */

package com.itheima.mp.service.impl;

import com.itheima.mp.configuration.MinioProperties;
import com.itheima.mp.service.IFileCommonService;
import com.itheima.mp.utils.StoreFileReturn;
import io.minio.*;
import io.minio.errors.*;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * @desc:
 * @author: weili23
 * @createTime: 2024/5/14 10:24
 * @version: v1.0
 */
@Service
public class FileCommonServiceImpl implements IFileCommonService {
    @Autowired(required=false)
    private MinioClient minioClient;
    @Autowired(required=false)
    private MinioProperties minioConfig;

    @Override
    public StoreFileReturn uploadFile(MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 设置存储桶名称和对象名称
        String bucketName = minioConfig.getBucketName();
        String originalFilename = file.getOriginalFilename();
        String fileSize = String.valueOf(file.getSize());
        String[] parts = originalFilename.split("\\.");
        String extension = parts[parts.length - 1];
        String objectName = UUID.randomUUID().toString()+"."+extension;

        // 检查存储桶是否存在，如果不存在则创建
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
        //文件上传
        minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(file.getInputStream(), file.getSize(), -1)
                .contentType(file.getContentType())
                .build());

        StoreFileReturn storePathExt = new StoreFileReturn();
        storePathExt.setFileName(file.getOriginalFilename());
        storePathExt.setPath(objectName);
        storePathExt.setFilePath(objectName);
        storePathExt.setGroup(bucketName);
        storePathExt.setFileExt(extension);
        storePathExt.setFileSize(fileSize);
        return storePathExt;
    }

    @Override
    public void downloadFile(String path, String filename, HttpServletResponse response) throws IOException {
        // 初始化 out
        ServletOutputStream out = response.getOutputStream();
        try {
            // 获取文件
            if (filename.lastIndexOf(".") == -1) {
                String suffix = path.substring(path.lastIndexOf(".") + 1);
                filename = filename + "." + suffix;
            }
            GetObjectResponse MP = minioClient.getObject(GetObjectArgs.builder().bucket(minioConfig.getBucketName()).object(path).build());
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(path.substring(path.lastIndexOf("/") + 1), "UTF-8"));
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            // 使用 out 而不是 output
            IOUtils.copy(MP, out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    @Override
    public void deleteFile(String path) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(path).build());
    }
}
